pub fn learn_smartpoint2() {
  _learn_box1();
  //_learn_rc();
  //_learn_rc_refcell();
}

fn _take_ownership(s: &String) {
  println!("hello {s}");
}

use std::cell::RefCell;
use std::rc::Rc;

trait State {
  fn next(self: Box<Self>)->Box<dyn State>;
}

struct User {
  // 结构体中的字段不能为空,移出所有权会有这个风险,因此需要改造
  // state: Box<dyn State>
  // 改造后
  state: Option<Box<dyn State>>
}

struct Remove {}
impl State for Remove {
  fn next(self: Box<Self>)->Box<dyn State>{
    self
  }
}
struct Stop {}
impl State for Stop {
  fn next(self: Box<Self>)->Box<dyn State>{
    self
  }
}
struct Normal {}
impl State for Normal {
  fn next(self: Box<Self>)->Box<dyn State>{
    self
  }
}

impl User {
  fn next(&mut self) {
    // self.state是Box,没有实现copy,需要移动
    // 但不能移动,因为移动(消费)后结构体的state字段就是空了,rust不允许结构体中有未填充的字段
    // 所以这里需要用option
    // self.state = self.state.next();
    if let Some(s)=self.state.take(){
      self.state = Some(s.next())
    }
  }
}

fn _learn_box0() {
  let mut x = Box::new(1);
  let y = Box::new(1);
  x=y;

  let mut j = Box::new(String::from("hello"));
  let k = Box::new(String::from("hello2"));
  j=k;

  let mut l:Box<dyn State> = Box::new(Normal{});
  let m:Box<dyn State> = Box::new(Stop{});
  l=m;
}

fn _learn_box1(){
  let mut a:Box<dyn State> = Box::new(Normal{});
  a = a.next();

  let mut user = User {
    state: Some(Box::new(Normal{}))
  };
  //user.next();
}

fn _learn_rc() {
  let a = Rc::new(String::from("diablo"));
  {
    let b = a.clone();
    println!("drop before:{}, {}, {}", a, b, Rc::strong_count(&b));
  }
  println!("rc:{}, {}", a, Rc::strong_count(&a));
}

fn _learn_refcell() {}

// 简单的组合使用的例子
fn _learn_rc_refcell() {
  let s = Rc::new(RefCell::new(String::from("hello")));
  let s1 = s.clone();
  let s2 = s.clone();

  println!("{:?}, {:?}, {:?}", s.borrow(), s1.borrow(), s2.borrow());
  s1.borrow_mut().push_str(" world");
  println!("s ref count:{}", Rc::strong_count(&s));
  println!("{:?}, {:?}, {:?}", s.borrow(), s1.borrow(), s2.borrow());
}
